home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / os2 / pmnos11s / lpc.c < prev    next >
C/C++ Source or Header  |  1993-07-30  |  24KB  |  1,093 lines

  1. /* LPC - Line Printer Spooler Control
  2.  *   written by David Johnson (dave@cs.olemiss.edu)
  3.  *
  4.  * This code is in the public domain.
  5.  *
  6.  * Revision History:
  7.  *
  8.  * Revision 1.2  91/09/26  dave (from Hans-Juergen Knobloch)
  9.  * Changed promote_job() to only promote job higher than the current
  10.  *     highest job instead of straight to 'A'
  11.  *
  12.  * Revision 1.1  91/09/19  dave
  13.  * Calls to lpq and lprm are now wrapped by a local function to add
  14.  *     argument to tell them not to use a new session
  15.  *
  16.  * Revision 1.0  91/09/04  dave
  17.  * Initial Release
  18.  *
  19.  */
  20. #include <stdio.h>
  21. #include <ctype.h>
  22. #include <time.h>
  23. #include <dir.h>
  24. #include "config.h"
  25. #include "global.h"
  26. #include "mbuf.h"
  27. #include "session.h"
  28. #include "cmdparse.h"
  29. #include "proc.h"
  30. #include "tty.h"
  31. #include "iface.h"
  32. #include "socket.h"
  33. #include "commands.h"
  34. #include "netuser.h"
  35. #include "dirutil.h"
  36. #include "lp.h"
  37. #include "lpd.h"
  38.  
  39.  
  40. /* in lpd.c */
  41. extern char *extract_parms __ARGS((char *local_parms, int extra));
  42. extern int  is_lpd_active __ARGS((void));
  43. extern int  is_job_specified __ARGS((char *cf_name));
  44.  
  45. /* in lpdunsp.c */
  46. extern void start_unspooler_task __ARGS((int s, void *queue, void *p));
  47.  
  48. /* in lpdsubr.c */
  49. extern int  clear_status_flag __ARGS((char *queue, int flag));
  50. extern int  get_job_count __ARGS((char *queue));
  51. extern int  get_job_list __ARGS((char *directory, struct job_entry **job_list));
  52. extern char **get_queue_list __ARGS((void));
  53. extern char *get_spool_dir __ARGS((char *queue));
  54. extern int  is_unspooler_active __ARGS((char *queue, char **job));
  55. extern int  kill_unspooler __ARGS((char *queue));
  56. extern int  read_status __ARGS((char *queue, unsigned int *flags, unsigned int *next_seq, char **message));
  57. extern int  set_status_flag __ARGS((char *queue, int flag));
  58. extern int  signal_queue __ARGS((char *queue));
  59.  
  60. /* in lpclient.c */
  61. #ifdef LPCLIENTS
  62. extern int  dolpq __ARGS((int argc,char *argv[],void *p));
  63. extern int  dolprm __ARGS((int argc,char *argv[],void *p));
  64. #endif
  65.  
  66. /* local functions */
  67. #ifdef LPCLIENTS
  68. static int  l_dolpq __ARGS((int argc,char *argv[],void *p));
  69. static int  l_dolprm __ARGS((int argc,char *argv[],void *p));
  70. #endif
  71. static int  doabort __ARGS((int argc,char *argv[],void *p));
  72. static int  doclean __ARGS((int argc,char *argv[],void *p));
  73. static int  docontinue __ARGS((int argc,char *argv[],void *p));
  74. static int  dodisable __ARGS((int argc,char *argv[],void *p));
  75. static int  dodown __ARGS((int argc,char *argv[],void *p));
  76. static int  doenable __ARGS((int argc,char *argv[],void *p));
  77. static int  dohelp __ARGS((int argc,char *argv[],void *p));
  78. static int  dokill __ARGS((int argc,char *argv[],void *p));
  79. static int  dolock __ARGS((int argc,char *argv[],void *p));
  80. static int  dolpd __ARGS((int argc,char *argv[],void *p));
  81. static int  doquit __ARGS((int argc,char *argv[],void *p));
  82. static int  dorestart __ARGS((int argc,char *argv[],void *p));
  83. static int  dostart __ARGS((int argc,char *argv[],void *p));
  84. static int  dostatus __ARGS((int argc,char *argv[],void *p));
  85. static int  dostop __ARGS((int argc,char *argv[],void *p));
  86. static int  dotopq __ARGS((int argc,char *argv[],void *p));
  87. static int  dounlock __ARGS((int argc,char *argv[],void *p));
  88. static int  doup __ARGS((int argc,char *argv[],void *p));
  89.  
  90. static int  getline __ARGS((struct session *sp,char *prompt,char *buf,int n));
  91.  
  92.  
  93. static struct cmds LPCcmds[] = {
  94.     "",        donothing,    0, 0, NULLCHAR,
  95.     "?",        dohelp,        0, 0, NULLCHAR,
  96.     "abort",    doabort,    0, 2, "abort ( all | <queue> ) [<queue> ...]",
  97.     "clean",    doclean,    0, 2, "clean ( all | <queue> ) [<queue> ...]",
  98.     "continue",    docontinue,    0, 1, "continue <queue>",
  99.     "disable",    dodisable,    0, 2, "disable ( all | <queue> ) [<queue> ...]",
  100.     "down",        dodown,        0, 2, "down ( all | <queue> ) [<queue> ...] [<message>]",
  101.     "enable",    doenable,    0, 2, "enable ( all | <queue> ) [<queue> ...]",
  102.     "help",        dohelp,        0, 0, NULLCHAR,
  103.     "kill",        dokill,        0, 2, "kill ( all | <queue> ) [<queue> ...]",
  104.     "lock",        dolock,        0, 0, NULLCHAR,
  105.     "lpd",        dolpd,        0, 0, NULLCHAR,
  106. #ifdef LPCLIENTS
  107.     "lprm",        l_dolprm,    0, 0, NULLCHAR,
  108.     "lpq",        l_dolpq,    0, 0, NULLCHAR,
  109. #endif
  110.     "quit",        doquit,        0, 0, NULLCHAR,
  111.     "restart",    dorestart,    0, 2, "restart ( all | <queue> ) [<queue> ...]",
  112.     "start",    dostart,    0, 2, "start ( all | <queue> ) [<queue> ...]",
  113.     "status",    dostatus,    0, 0, NULLCHAR,
  114.     "stop",        dostop,        0, 2, "stop ( all | <queue> ) [<queue> ...]",
  115.     "topq",        dotopq,        0, 2, "topq <queue> <job> [<job>...]",
  116.     "unlock",    dounlock,    0, 0, NULLCHAR,
  117.     "up",        doup,        0, 2, "up ( all | <queue> ) [<queue> ...]",
  118.     NULLCHAR,    NULLFP,        0, 0, "Unknown command",
  119. };
  120.  
  121. char *help_strings[] = {
  122.     "? is same as 'help'",
  123.     "abort ( all | <queue> ): kill off server and disable printing",
  124.     "clean ( all | <queue> ): kill off server and remove spooler files from queue",
  125.     "continue <queue>: continue a single-sheet job",
  126.     "disable ( all | <queue> ): disable queueing",
  127.     "down ( all | <queue> ) (<message>): take printer down with message",
  128.     "enable ( all | <queue> ): enable queuing",
  129.     "help [all] [<command>]: print command summary",
  130.     "kill ( all | <queue> ): kill off server and then restart printing",
  131.     "lock : lock out maintenance commands",
  132.     "lpd : check out lpd process",
  133. #ifdef LPCLIENTS
  134.     "lpq <parms>: call lpq",
  135.     "lprm <parms>: call lprm",
  136. #endif
  137.     "quit : terminate; return to NOS command mode",
  138.     "restart ( all | <queue> ): start a server",
  139.     "start ( all | <queue> ): enable printing and start server",
  140.     "status [<queue>]: print status",
  141.     "stop ( all | <queue> ): disable further printing",
  142.     "topq <queue> (user|jobnumber): move job to top of queue",
  143.     "unlock : allow maintenance command usage",
  144.     "up ( all | <queue> ): bring printer back into service",
  145.     NULLCHAR
  146. };
  147.  
  148. static int Slpc = -1;    /* not actually socket; used to allow only one */
  149.             /* lpc to be active at a time */
  150.  
  151. static int locked = 0;
  152. static char passwd[11];    /* lock password */
  153.  
  154. /* Handle top-level LPC command */
  155. int
  156. dolpc(argc,argv,p)
  157. int argc;
  158. char *argv[];
  159. void *p;
  160. {
  161.     struct session *sp;
  162.     char *buf, **pr, **opr;
  163.     unsigned int flags, next_seq;
  164.     char *message;
  165.  
  166.     if( Slpc != -1 ) {
  167.         /* Already running! */
  168.         tprintf( "LPC is already active\n" );
  169.         return 0;
  170.     }
  171.     Slpc = 1;    /* running */
  172.  
  173.     /* Allocate a session control block */
  174.     if((sp = newsession(argv[1],LPUTILS)) == NULLSESSION){
  175.         tprintf("Too many sessions\n");
  176.         return 1;
  177.     }
  178.  
  179.     /* look for printers which are currently paused */
  180.     for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  181.         read_status( *pr, &flags, &next_seq, &message );
  182.         if( flags & PAUSED )
  183.             tprintf( "Queue %s is paused\n", *pr );
  184.         free( *pr );
  185.     }
  186.     if( opr ) {
  187.         free( *pr );    /* null entry */
  188.         free( opr );
  189.     }
  190.  
  191.     /* process commands */
  192.     buf = mallocw( LINELEN );
  193.     do {
  194.         getline( sp, "lpc> ", buf, LINELEN );
  195.         cmdparse( LPCcmds, buf, NULL );
  196.  
  197.     } while( Slpc > 0 );        /* quit sets to 0 */
  198.     free( buf );
  199.  
  200.     freesession( sp );
  201.     Slpc = -1;    /* not running */
  202.     return 0;
  203. }
  204.  
  205. #ifdef LPCLIENTS
  206.  
  207. static int
  208. l_dolpq(argc,argv,p)
  209. int argc;
  210. char *argv[];
  211. void *p;
  212. {
  213.     int i;
  214.     char **pargv, *strdup();
  215.  
  216.     pargv = (char **)callocw(argc+1,sizeof(char *));
  217.     for(i=0;i<argc;i++)
  218.         pargv[i] = strdup(argv[i]);
  219.     pargv[argc] = "-c";    /* tell lpq to not allocate a session */
  220.  
  221.     dolpq(argc+1,pargv,p);
  222.  
  223.     for(i=0;i<argc;i++)
  224.         free( pargv[i] );
  225.     free( pargv );
  226.     return 0;
  227. }
  228.  
  229. static int
  230. l_dolprm(argc,argv,p)
  231. int argc;
  232. char *argv[];
  233. void *p;
  234. {
  235.     int i;
  236.     char **pargv, *strdup();
  237.  
  238.     pargv = (char **)callocw(argc+1,sizeof(char *));
  239.     for(i=0;i<argc;i++)
  240.         pargv[i] = strdup(argv[i]);
  241.     pargv[argc] = "-c";    /* tell lprm to not allocate a session */
  242.  
  243.     dolprm(argc+1,pargv,p);
  244.  
  245.     for(i=0;i<argc;i++)
  246.         free( pargv[i] );
  247.     free( pargv );
  248.     return 0;
  249. }
  250. #endif    /* LPCLIENTS */
  251.  
  252. static int
  253. doabort(argc,argv,p)
  254. int argc;
  255. char *argv[];
  256. void *p;
  257. {
  258.     int index = 1;
  259.     char *queue, **pr, **opr;
  260.  
  261.     if( locked )
  262.         return 0;
  263.  
  264.     dostop( argc, argv, p );
  265.  
  266.     if( strcmp( argv[1], "all" ) == 0 ) {
  267.         /* all printers */
  268.  
  269.         for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  270.             if( kill_unspooler( *pr ) > 0 )
  271.                 tprintf( "%s: server killed\n", *pr );
  272.             free( *pr );
  273.         }
  274.         if( opr ) {
  275.             free( *pr );    /* null entry */
  276.             free( opr );
  277.         }
  278.     } else {
  279.         /* specific list of printers */
  280.         while( index < argc ) {
  281.             queue = argv[ index ];
  282.             if( kill_unspooler( queue ) > 0 )
  283.                 tprintf( "%s: server killed\n", queue );
  284.             index++;
  285.         }
  286.     }
  287.     return 0;
  288. }
  289.  
  290. static void
  291. clean_directory(directory)
  292. char *directory;
  293. {
  294.     char *path;
  295.     struct ffblk file_info;
  296.  
  297.     path = pathname( directory, "*.*" );
  298.     if( findfirst( path, &file_info, 0 ) == 0 ) {
  299.         free( path );
  300.         if( *(file_info.ff_name + 1) == 'F' ) {
  301.             switch( *file_info.ff_name ) {
  302.                 case 'C':
  303.                 case 'D':
  304.                     path = pathname( directory, file_info.ff_name );
  305.                     remove( path );
  306.                     free( path );
  307.                     tprintf( "removed %s\n", file_info.ff_name );
  308.                     break;
  309.             }
  310.         }
  311.         while( findnext( &file_info ) == 0 ) {
  312.             if( *(file_info.ff_name + 1) == 'F' ) {
  313.                 switch( *file_info.ff_name ) {
  314.                     case 'C':
  315.                     case 'D':
  316.                         path = pathname( directory, file_info.ff_name );
  317.                         remove( path );
  318.                         free( path );
  319.                         tprintf( "removed %s\n", file_info.ff_name );
  320.                         break;
  321.                 }
  322.             }
  323.         }
  324.     } else
  325.         free( path );
  326. }
  327.  
  328. static int
  329. doclean(argc,argv,p)
  330. int argc;
  331. char *argv[];
  332. void *p;
  333. {
  334.     int index = 1;
  335.     char *queue, **pr, **opr;
  336.     char *sd;
  337.  
  338.     if( locked )
  339.         return 0;
  340.  
  341.     if( strcmp( argv[1], "all" ) == 0 ) {
  342.         /* all printers */
  343.  
  344.         for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  345.             if( (sd = get_spool_dir( *pr )) == NULL )
  346.                 continue;
  347.             clear_status_flag( *pr, PRINT_ENABLED&PAUSED );
  348.             clean_directory( sd );
  349.             if( kill_unspooler( *pr ) > 0 )
  350.                 tprintf( "%s: server killed\n", *pr );
  351.             set_status_flag( *pr, PRINT_ENABLED );
  352.             free( sd );
  353.             free( *pr );
  354.         }
  355.         if( opr ) {
  356.             free( *pr );    /* null entry */
  357.             free( opr );
  358.         }
  359.     } else {
  360.         /* specific list of printers */
  361.         while( index < argc ) {
  362.             queue = argv[ index ];
  363.             if( (sd = get_spool_dir( queue )) == NULL )
  364.                 continue;
  365.             clear_status_flag( *pr, PRINT_ENABLED&PAUSED );
  366.             clean_directory( sd );
  367.             if( kill_unspooler( *pr ) > 0 )
  368.                 tprintf( "%s: server killed\n", *pr );
  369.             set_status_flag( *pr, PRINT_ENABLED );
  370.             free( sd );
  371.             index++;
  372.         }
  373.     }
  374.     return 0;
  375. }
  376.  
  377. static int
  378. docontinue(argc,argv,p)
  379. int argc;
  380. char *argv[];
  381. void *p;
  382. {
  383.     int index = 1;
  384.     char *queue;
  385.  
  386.     /* specific list of printers */
  387.     while( index < argc ) {
  388.         queue = argv[ index ];
  389.         signal_queue( queue );
  390.         index++;
  391.     }
  392. }
  393.  
  394. static int
  395. dodisable(argc,argv,p)
  396. int argc;
  397. char *argv[];
  398. void *p;
  399. {
  400.     int index = 1;
  401.     char *queue, **pr, **opr;
  402.  
  403.     if( locked )
  404.         return 0;
  405.  
  406.     if( strcmp( argv[1], "all" ) == 0 ) {
  407.         /* all printers */
  408.  
  409.         for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  410.             clear_status_flag( *pr, QUEUE_ENABLED );
  411.             free( *pr );
  412.         }
  413.         if( opr ) {
  414.             free( *pr );    /* null entry */
  415.             free( opr );
  416.         }
  417.     } else {
  418.         /* specific list of printers */
  419.         while( index < argc ) {
  420.             queue = argv[ index ];
  421.             clear_status_flag( queue, QUEUE_ENABLED );
  422.             index++;
  423.         }
  424.     }
  425. }
  426.  
  427. static int
  428. dodown(argc,argv,p)
  429. int argc;
  430. char *argv[];
  431. void *p;
  432. {
  433.     int index = 1;
  434.     char *queue, **pr, **opr;
  435.     char *path, *sd;
  436.     char message[256];
  437.     FILE *fp;
  438.  
  439.     if( locked )
  440.         return 0;
  441.  
  442.     *message = NULL;
  443.  
  444.     if( strcmp( argv[1], "all" ) == 0 ) {
  445.         /* all printers */
  446.  
  447.         for( opr = pr = get_queue_list(); pr && *pr; ++pr )
  448.             clear_status_flag( *pr, QUEUE_ENABLED|PRINT_ENABLED );
  449.  
  450.         /* save message */
  451.         index = 2;
  452.         while( index < argc ) {
  453.             strcat( message, argv[ index ] );
  454.             strcat( message, " " );
  455.             index++;
  456.         }
  457.         /* Now record status message in each queue status file */
  458.  
  459.         for( pr = opr; pr && *pr; ++pr ) {
  460.             if( (sd = get_spool_dir( *pr )) == NULL )
  461.                 break;
  462.             path = pathname( sd, D_STATUS );
  463.             if( (fp = fopen( path, "w" )) != NULL ) {
  464.                 fputs( message, fp );
  465.                 putc( '\n', fp );
  466.                 fclose( fp );
  467.             }
  468.             free( path );
  469.             free( sd );
  470.  
  471.             free( *pr );
  472.         }
  473.         if( opr ) {
  474.             free( *pr );    /* null entry */
  475.             free( opr );
  476.         }
  477.     } else {
  478.         /* specific list of printers */
  479.         while( index < argc ) {
  480.             queue = argv[ index ];
  481.             if( clear_status_flag( queue, QUEUE_ENABLED|PRINT_ENABLED ) < 0 ) {
  482.                 /* queue not recognized; must be start of message */
  483.  
  484.                 while( index < argc ) {
  485.                     strcat( message, argv[ index ] );
  486.                     strcat( message, " " );
  487.                     index++;
  488.                 }
  489.             } else
  490.                 index++;
  491.         }
  492.  
  493.         /* Now record message in each queue status file */
  494.  
  495.         index = 1;
  496.         while( index < argc ) {
  497.             queue = argv[ index ];
  498.             if( (sd = get_spool_dir( queue )) == NULL ) {
  499.                 /* end of recognized queues; start of message */
  500.                 break;
  501.             }
  502.             path = pathname( sd, D_STATUS );
  503.             if( (fp = fopen( path, "w" )) != NULL ) {
  504.                 fputs( message, fp );
  505.                 putc( '\n', fp );
  506.                 fclose( fp );
  507.             }
  508.             free( path );
  509.             free( sd );
  510.             index++;
  511.         }
  512.     }
  513.  
  514.  
  515. }
  516.  
  517. static int
  518. doenable(argc,argv,p)
  519. int argc;
  520. char *argv[];
  521. void *p;
  522. {
  523.     int index = 1;
  524.     char *queue, **pr, **opr;
  525.  
  526.     if( locked )
  527.         return 0;
  528.  
  529.     if( strcmp( argv[1], "all" ) == 0 ) {
  530.         /* all printers */
  531.  
  532.         for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  533.             set_status_flag( *pr, QUEUE_ENABLED );
  534.             free( *pr );
  535.         }
  536.         if( opr ) {
  537.             free( *pr );    /* null entry */
  538.             free( opr );
  539.         }
  540.     } else {
  541.         /* specific list of printers */
  542.         while( index < argc ) {
  543.             queue = argv[ index ];
  544.             set_status_flag( queue, QUEUE_ENABLED );
  545.             index++;
  546.         }
  547.     }
  548. }
  549.  
  550. static int
  551. dohelp(argc,argv,p)
  552. int argc;
  553. char *argv[];
  554. void *p;
  555. {
  556.     int index = 0, command_length, line_count;
  557.     char **hp, *cp, *command, *tp, temp[16];
  558.  
  559.     if( argc < 2 ) {
  560.         hp = help_strings;
  561.         line_count = 0;
  562.         while( *hp ) {
  563.             cp = *hp++;
  564.             tp = temp;
  565.             while( *cp != ' ' )
  566.                 *tp++ = *cp++;
  567.             *tp = NULL;
  568.             tprintf( "%-15s", temp );
  569.             if( ++line_count > 4 ) {
  570.                 tputc( '\n' );
  571.                 line_count = 0;
  572.             } else
  573.                 tputc( ' ' );
  574.         }
  575.         tputc( '\n' );
  576.     } else {
  577.         if( strcmp( argv[1], "all" ) == 0 ) {
  578.             /* all commands */
  579.  
  580.             hp = help_strings;
  581.             while( *hp ) {
  582.                 tputs( *hp++ );
  583.                 tputc( '\n' );
  584.             }
  585.         } else {
  586.             /* specific list of commands */
  587.             while( ++index < argc ) {
  588.                 command = argv[ index ];
  589.                 command_length = strlen( command );
  590.                 hp = help_strings;
  591.                 while( *hp && strncmp( command, *hp, command_length ) != 0 )
  592.                     ++hp;
  593.                 if( *hp ) {
  594.                     tputs( *hp );
  595.                     tputc( '\n' );
  596.                 }
  597.             }
  598.         }
  599.     }
  600.     return 0;
  601. }
  602.  
  603. static int
  604. dokill(argc,argv,p)
  605. int argc;
  606. char *argv[];
  607. void *p;
  608. {
  609.     if( locked )
  610.         return 0;
  611.  
  612.     doabort( argc, argv, p );
  613.     return( dostart( argc, argv, p ) );
  614. }
  615.  
  616. static int
  617. dolock(argc,argv,p)
  618. int argc;
  619. char *argv[];
  620. void *p;
  621. {
  622.     int length;
  623.  
  624.     if( locked )
  625.         return 0;
  626.  
  627.     if( !is_lpd_active() )
  628.         tprintf( "Warning: LPD is not active\n" );
  629.  
  630.     Current->ttystate.echo = 0;        /* Echo OFF */
  631.  
  632.     length = getline( Current, "Enter Password: ", passwd, 10 );
  633.  
  634.     Current->ttystate.echo = 1;        /* Echo ON */
  635.     tprintf( "\n\n" );
  636.  
  637.     if( length > 0 ) {
  638.         locked = 1;
  639.         tprintf( "Restricted mode enabled\n" );
  640.     } else {
  641.         tprintf( "not locked\n" );
  642.     }
  643.     return 0;
  644. }
  645.  
  646. static int
  647. dolpd(argc,argv,p)
  648. int argc;
  649. char *argv[];
  650. void *p;
  651. {
  652.     if( is_lpd_active() )
  653.         tprintf( "Active LPD\n" );
  654.     else
  655.         tprintf( "LPD is not active\n" );
  656.  
  657.     return 0;
  658. }
  659.  
  660. static int
  661. doquit(argc,argv,p)
  662. int argc;
  663. char *argv[];
  664. void *p;
  665. {
  666.     if( locked )
  667.         return 0;
  668.  
  669.     Slpc = 0;
  670.  
  671.     return 0;
  672. }
  673.  
  674. static int
  675. dorestart(argc,argv,p)
  676. int argc;
  677. char *argv[];
  678. void *p;
  679. {
  680.     int index = 1;
  681.     char *queue, **pr, **opr, *printer;
  682.  
  683.     if( locked )
  684.         return 0;
  685.  
  686.     if( !is_lpd_active() ) {
  687.         tprintf( "LPD is not active\n" );
  688.         return 0;
  689.     }
  690.     if( strcmp( argv[1], "all" ) == 0 ) {
  691.         /* all printers */
  692.  
  693.         for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  694.             printer = strdup( *pr );        /* child will free */
  695.             newproc("LPDprint",2048,start_unspooler_task,0,(void *)printer,NULL,0);
  696.             free( *pr );
  697.         }
  698.         if( opr ) {
  699.             free( *pr );    /* null entry */
  700.             free( opr );
  701.         }
  702.     } else {
  703.         /* specific list of printers */
  704.         while( index < argc ) {
  705.             queue = argv[ index ];
  706.             printer = strdup( queue );        /* child will free */
  707.             newproc("LPDprint",2048,start_unspooler_task,0,(void *)printer,NULL,0);
  708.             index++;
  709.         }
  710.     }
  711. }
  712.  
  713. static int
  714. dostart(argc,argv,p)
  715. int argc;
  716. char *argv[];
  717. void *p;
  718. {
  719.     int index = 1;
  720.     char *queue, **pr, **opr;
  721.  
  722.     if( locked )
  723.         return 0;
  724.  
  725.     if( strcmp( argv[1], "all" ) == 0 ) {
  726.         /* all printers */
  727.  
  728.         for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  729.             set_status_flag( *pr, PRINT_ENABLED );
  730.             free( *pr );
  731.         }
  732.         if( opr ) {
  733.             free( *pr );    /* null entry */
  734.             free( opr );
  735.         }
  736.     } else {
  737.         /* specific list of printers */
  738.         while( index < argc ) {
  739.             queue = argv[ index ];
  740.             set_status_flag( queue, PRINT_ENABLED );
  741.             index++;
  742.         }
  743.     }
  744.     return( dorestart( argc, argv, p ) );
  745. }
  746.  
  747. static int
  748. show_queue_status( queue )
  749. char *queue;
  750. {
  751. #define QUEUE_STATUS(flags)    ((flags) & QUEUE_ENABLED ? "enabled " : "disabled")
  752. #define PRINT_STATUS(flags)    ((flags) & PRINT_ENABLED ? "enabled " : "disabled")
  753.  
  754.     int active;
  755.     unsigned int flags, next_seq;
  756.     int job_count;
  757.     char *message;
  758.     char *job;
  759.  
  760. /*    tprintf( "show_queue_status( %s )\n", queue );
  761.     tflush(); */
  762.  
  763.     if( read_status( queue, &flags, &next_seq, &message ) < 0 ) {
  764.         tprintf( "%-14s\n  does not exist\n", queue );
  765.     } else {
  766.         active = is_unspooler_active( queue, &job );
  767.         job_count = get_job_count( queue );
  768.  
  769.         tprintf( "%-16s%4d    %-10s%s ", queue, job_count,
  770.             QUEUE_STATUS(flags), PRINT_STATUS(flags) );
  771.         if( active ) {
  772.             tprintf( "(unspooler " );
  773.             if( flags & PAUSED )
  774.                 tprintf( "paused" );
  775.             else
  776.                 tprintf( "active" );
  777.             if( job )
  778.                 tprintf( ", job %s", job );
  779.             tprintf( ")\n" );
  780.         } else
  781.             tprintf( "(no unspooler)\n" );
  782.  
  783.         tprintf( "  %s\n", message );
  784.     }
  785. }
  786.  
  787. static int
  788. dostatus(argc,argv,p)
  789. int argc;
  790. char *argv[];
  791. void *p;
  792. {
  793.     int index = 1;
  794.     char *queue, **pr, **opr;
  795.  
  796.     tputs( "Queue           Jobs    Queueing  Printing\n" );
  797.     if( argc < 2 ) {        /* must want all printers */
  798.         for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  799.             show_queue_status( *pr );
  800.             free( *pr );
  801.         }
  802.         if( opr ) {
  803.             free( *pr );    /* null entry */
  804.             free( opr );
  805.         }
  806.     } else {
  807.         while( index < argc ) {
  808.             queue = argv[ index ];
  809.             show_queue_status( queue );
  810.             index++;
  811.         }
  812.     }
  813.     return 0;
  814. }
  815.  
  816. static int
  817. dostop(argc,argv,p)
  818. int argc;
  819. char *argv[];
  820. void *p;
  821. {
  822.     int index = 1;
  823.     char *queue, **pr, **opr;
  824.  
  825.     if( locked )
  826.         return 0;
  827.  
  828.     if( strcmp( argv[1], "all" ) == 0 ) {
  829.         /* all printers */
  830.  
  831.         for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  832.             clear_status_flag( *pr, PRINT_ENABLED );
  833.             free( *pr );
  834.         }
  835.         if( opr ) {
  836.             free( *pr );    /* null entry */
  837.             free( opr );
  838.         }
  839.     } else {
  840.         /* specific list of printers */
  841.         while( index < argc ) {
  842.             queue = argv[ index ];
  843.             clear_status_flag( queue, PRINT_ENABLED );
  844.             index++;
  845.         }
  846.     }
  847. }
  848.  
  849. static int
  850. dotopq(argc,argv,p)
  851. int argc;
  852. char *argv[];
  853. void *p;
  854. {
  855.     int i, job, job_count, buffer_size, modified = 0;
  856.     char *sd, *buffer;
  857.     struct job_entry *job_list;
  858.  
  859.     if( locked )
  860.         return 0;
  861.  
  862.     tprintf( "%s:\n", argv[1] );
  863.  
  864.     if( (sd = get_spool_dir( argv[1] )) == NULL )
  865.         return -1;
  866.  
  867.     /*
  868.      * Figure out buffer size for extract_parms()
  869.      */
  870.     buffer_size = 0;
  871.     for( i = 1; i < argc; i++ )
  872.         buffer_size += strlen( argv[ i ] ) + 1;    /* plus space */
  873.  
  874.     buffer = (char *)mallocw( buffer_size );
  875.  
  876.     for( i = 1; i < argc; i++ ) {
  877.         strcat( buffer, argv[ i ] );
  878.         if( i+1 < argc )
  879.             strcat( buffer, " " );
  880.     }
  881.  
  882.     (void)extract_parms( buffer, 1 );
  883.     free( buffer );
  884.  
  885.     job_count = get_job_list( sd, &job_list );
  886.  
  887.     for( job = 0; job < job_count; job++ ) {
  888.  
  889.         if( !is_job_specified( job_list[ job ].j_name ) )
  890.             continue;
  891.  
  892.         /*
  893.          * Promote job to top of queue
  894.          */
  895.         if( promote_job( sd, job_list[ job ].j_name,
  896.                 job_list[ 0 ].j_name[2] ) < 0 )
  897.             continue;
  898.  
  899.         modified++;
  900.         free( job_list[ job ].j_name );
  901.         job_list[ job ].j_name = NULL;
  902.     }
  903.  
  904.     /*
  905.      * Put other high priority jobs lower
  906.      */
  907.     if( !modified ) {
  908.         for( job = 0; job < job_count; job++ ) {
  909.             if( job_list[ job ].j_name )
  910.                 free( job_list[ job ].j_name );
  911.         }
  912.         free( job_list );
  913.         return 0;
  914.     }
  915.     for( job = 0; job < job_count; job++ ) {
  916.         if( job_list[ job ].j_name && job_list[ job ].j_name[2] == 'A' ) {
  917.             touch( sd, job_list[ job ].j_name );
  918.             free( job_list[ job ].j_name );
  919.         } else {
  920.             free( job_list[ job ].j_name );
  921.         }
  922.     }
  923.     free( job_list );
  924.     free( sd );
  925.  
  926.     tprintf( "queue order changed\n" );
  927.  
  928.     /*
  929.      * Force unspooler to rebuild the queue after current job
  930.      */
  931.     set_status_flag( argv[1], FORCE_REQUE );
  932.  
  933.     return 0;
  934. }
  935.  
  936. static int
  937. promote_job( directory, cf_name, prior )
  938. char *directory, *cf_name, prior;
  939. {
  940.     char buffer[16], *source_path, *dest_path;
  941.  
  942.     strcpy( buffer, cf_name );
  943.     if( prior > 'A')
  944.         prior--;
  945.     buffer[ 2 ] = prior;
  946.  
  947.     if( strcmp( buffer, cf_name ) == 0 )
  948.         return -1;            /* already high priority */
  949.  
  950.     source_path = pathname( directory, cf_name );
  951.     dest_path = pathname( directory, buffer );
  952.  
  953.     if( rename( source_path, dest_path ) < 0 ) {
  954.         free( source_path );
  955.         free( dest_path );
  956.         return -1;
  957.     }
  958.     tprintf( "promoting %s to %s\n", cf_name, buffer );
  959.  
  960.     free( source_path );
  961.     free( dest_path );
  962.  
  963.     return 0;
  964. }
  965.  
  966. static int
  967. touch( directory, cf_name )
  968. char *directory, *cf_name;
  969. {
  970.     int c;
  971.     char *path;
  972.     FILE *fp;
  973.  
  974.     path = pathname( directory, cf_name );
  975.     if( (fp = fopen( path, "rw" )) == NULL ) {
  976.         free( path );
  977.         return -1;
  978.     } else if( (c = getc( fp )) == EOF )
  979.         goto finish;
  980.     else if( fseek( fp, 0L, 0 ) < 0 )
  981.         goto finish;
  982.     else if( putc( c, fp ) == EOF )
  983.         goto finish;
  984.     else if( fflush( fp ) == EOF )
  985.         goto finish;
  986.  
  987. finish:    if( fp != NULL )
  988.         fclose( fp );
  989.     free( path );
  990.  
  991.     return 0;
  992. }
  993.  
  994. static int
  995. dounlock(argc,argv,p)
  996. int argc;
  997. char *argv[];
  998. void *p;
  999. {
  1000.     int length;
  1001.     char lpasswd[11];
  1002.  
  1003.     if( locked == 0 )
  1004.         return 0;
  1005.  
  1006.     if( !is_lpd_active() )
  1007.         tprintf( "Warning: LPD is not active\n" );
  1008.  
  1009.     Current->ttystate.echo = 0;        /* Echo OFF */
  1010.  
  1011.     length = getline( Current, "Enter Password: ", lpasswd, 10 );
  1012.  
  1013.     Current->ttystate.echo = 1;        /* Echo ON */
  1014.     tprintf( "\n\n" );
  1015.  
  1016.     if( length > 0 ) {
  1017.         if( strcmp( passwd, lpasswd ) == 0 ) {
  1018.             locked = 0;
  1019.             tprintf( "Restricted mode canceled\n" );
  1020.         } else
  1021.             tprintf( "Invalid password.\n" );
  1022.     } else {
  1023.         tprintf( "Restricted mode\n" );
  1024.     }
  1025.     return 0;
  1026. }
  1027.  
  1028. static int
  1029. doup(argc,argv,p)
  1030. int argc;
  1031. char *argv[];
  1032. void *p;
  1033. {
  1034.     int index = 1;
  1035.     char *queue, **pr, **opr;
  1036.     char *path, *sd;
  1037.  
  1038.     if( locked )
  1039.         return 0;
  1040.  
  1041.     if( strcmp( argv[1], "all" ) == 0 ) {
  1042.         /* all printers */
  1043.  
  1044.         for( opr = pr = get_queue_list(); pr && *pr; ++pr ) {
  1045.             set_status_flag( *pr, QUEUE_ENABLED|PRINT_ENABLED );
  1046.  
  1047.             /* delete status file */
  1048.             if( (sd = get_spool_dir( *pr )) != NULL ) {
  1049.                 path = pathname( sd, D_STATUS );
  1050.                 remove( path );
  1051.                 free( path );
  1052.                 free( sd );
  1053.             }
  1054.             free( *pr );
  1055.         }
  1056.         if( opr ) {
  1057.             free( *pr );    /* null entry */
  1058.             free( opr );
  1059.         }
  1060.     } else {
  1061.         /* specific list of printers */
  1062.         while( index < argc ) {
  1063.             queue = argv[ index ];
  1064.             set_status_flag( queue, QUEUE_ENABLED|PRINT_ENABLED );
  1065.  
  1066.             /* delete status file */
  1067.             if( (sd = get_spool_dir( queue )) != NULL ) {
  1068.                 path = pathname( sd, D_STATUS );
  1069.                 remove( path );
  1070.                 free( path );
  1071.                 free( sd );
  1072.             }
  1073.             index++;
  1074.         }
  1075.     }
  1076. }
  1077.  
  1078. /* Issue a prompt and read a line from the user */
  1079. static int
  1080. getline(sp,prompt,buf,n)
  1081. struct session *sp;
  1082. char *prompt;
  1083. char *buf;
  1084. int n;
  1085. {
  1086.     /* If there's something already there, don't issue prompt */
  1087.     if(socklen(sp->input,0) == 0)
  1088.         tprintf(prompt);
  1089.  
  1090.     usflush(sp->output);
  1091.     return recvline(sp->input,buf,n);
  1092. }
  1093.